/*
 @Name: code插件
 @Author: ray
 @License: MIT
*/
; rayui.define(function (exports) {
    "use strict";

    var $ = rayui.$,
        plugName = "code",
        $body = $('body'),
        dataCache = {},
        globalIndex = 1000,
        regexInnerPre = /<pre.*?<\/pre>\n/g,
        tempReplace = "RAYUICODEREPALACEX@!90",
        styleStartReplace = "RAYUICODESTART@!90",
        styleEndReplace = "RAYUICODEEND@!90",
        styleStartReg = /RAYUICODESTART@!90/g,
        styleEndReg = /RAYUICODEEND@!90/g,
        globalOptions = { styleLabel: "rs"},
        makeReg = function (str) {
            return new RegExp("<" + str + "(.*?)</" + str +">", 'g');
        },
        render = function (container) {
            var optionsFunc = (typeof container === "string" || container instanceof jQuery) ? { container: container } : (container || {}),
                $pres = $("pre.rayui-code", optionsFunc.container ? container : "body"),
                elems = [];
            $pres.each(function () {
                $(this).attr("data-index", globalIndex);
                dataCache[globalIndex++] = $(this).html();
                elems.push(this);
            });

            $.each(elems.reverse(), function () {
                var $this = $(this),
                    localOption = $this.data("options"),
                    options = typeof localOption === "string"
                        ? $.extend({}, globalOptions, optionsFunc)
                        : $.extend({}, globalOptions, optionsFunc, localOption),
                    styleReg = makeReg(options.styleLabel),
                    html = $this.html();
                 
                //预处理样式类型标签
                html = html.replace(styleReg, styleStartReplace + "$1" + styleEndReplace);
                 
                //转译html，这里需要排除内嵌的<pre>
                var list = html.match(regexInnerPre);
                //先替换成临时字符
                html = html.replace(regexInnerPre, tempReplace);
                html = html.replace(/</g, '&lt;');//.replace(/>/g, '&gt;');
                //把临时字符替换回去
                for (var i in list) {
                    html = html.replace(tempReplace, list[i]);
                }

                //替换处理样式类型标签
                html = html.replace(styleStartReg, "<span ").replace(styleEndReg, "<span>");
                

                $this.html('<ol><li>' + html.replace(/\n/g, '</li><li>') + '</li></ol>');
                
                var $ol = $this.find(">ol"), $lis = $ol.find('>li');

                //皮肤支持
                options.skin && $this.addClass('rayui-' + options.skin);

                //各行变色
                options.even && $this.addClass('rayui-even');

                //设置标题
                if (options.title || options.copy) {
                    options.$head = $('<div class="rayui-code-head"/>').prependTo($this);
                    options.$title = $('<span class="rayui-code-title">' + (options.title || "&nbsp;") + '</span>').appendTo(options.$head);
                    //设置标题样式
                    options.titleStyle && options.$title.prop("style", options.titleStyle);
                }

                //复制，嵌套复制按钮无效
                if (options.copy && $this.data('html')) {
                    options.$tool = $('<div class="rayui-code-tool"></div>').prependTo(options.$head);
                    $('<span class=" btn-copy"><i class="ra ra-copy"></i></span>').appendTo(options.$tool);
                }
                
                //空格替换为点号
                if (options.blankToChar) {
                    options.blankToChar === true && (options.blankToChar = '-');
                    var regex = /^\s+(?=\S)/;
                    $lis.each(function () {
                        var html = $(this).html(),
                            list = html.split(regex);
                        if (list.length === 2) {
                            var str = [], count = html.length - list[1].length;
                            while (count-- > 0) str.push('<span class="rayui-code-dashed">' + options.blankToChar + '</span>');
                            str.push('<span>' + list[1] + '</span>');
                            $(this).html(str.join(''));
                        }
                    });
                }

                //按行数适配左边距
                var rows = ("" + $lis.length).length;
                $lis.css('margin-left', (rows * 10 + 10) + 'px');

                //设置ol高度
                options.height && $ol.css("max-height", options.height - (options.$head ? options.$head.outerHeight() : 0) - 2);
            });
        };

    $body.on("click." + plugName, '.rayui-code .rayui-code-tool>.btn-copy', function () {
        var $p = $(this).closest('.rayui-code'), $ol = $p.find(">ol"), i = $p.data('index'), $area = $p.find(">.rayui-textarea");
        $(this).toggleClass("btn-copy-back");
        if ($area.length === 0) {
            $('<textarea class="rayui-textarea"></textarea>').css({
                width: $ol.outerWidth(),
                height: $ol.outerHeight()
            }).val(dataCache[i]).appendTo($p);
        } else {
            $area.remove();
        }
        $ol.toggleClass("hidden");
    });

    var codeHandle = {
        render: function (container) {
            render(container);
        }
    };

    exports(plugName, codeHandle);
}, rayui.jsAsync());
